package com.example.securitymanagement.config;


import com.example.securitymanagement.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.JdbcUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.sql.DataSource;

@EnableWebSecurity// 开启MVC Security安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Qualifier("dataSource")
    @Autowired
    private DataSource dataSource;


    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //设置密码编码器
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();


        /*内存身份认证
         构建用户，模拟了测试用户*/
       /* InMemoryUserDetailsManagerConfigurer inMemoryUserDetailsManagerConfigurer =auth.inMemoryAuthentication().passwordEncoder(bCryptPasswordEncoder);
            //设置用户名，密码                                                                                // .roles:设置角色
        inMemoryUserDetailsManagerConfigurer.withUser("dwy").password(bCryptPasswordEncoder.encode("123")).roles("comment");
        inMemoryUserDetailsManagerConfigurer.withUser("杜伟毅").password(bCryptPasswordEncoder.encode("123")).roles("vip");

        */

        /*使用jdbc进行身份认证
         *
         * 对于用户流量较大的项目来说，频繁的使用JDBC进行数据库查询认证不仅麻烦，而且会降低网站登录访问速度。对于一个完善的项目来说，如果某些业务已经实现了用户信息查询的服务，就没必要使用JDBC进行身份认证了。
         */

        /*JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> authenticationManagerBuilderJdbcUserDetailsManagerConfigurerr = auth.jdbcAuthentication().passwordEncoder(bCryptPasswordEncoder);
        authenticationManagerBuilderJdbcUserDetailsManagerConfigurerr.dataSource(dataSource);
        authenticationManagerBuilderJdbcUserDetailsManagerConfigurerr.usersByUsernameQuery("select username,password,valid from t_customer where username=?");
        authenticationManagerBuilderJdbcUserDetailsManagerConfigurerr.authoritiesByUsernameQuery("select c.username,a.authority from t_customer c,t_authority a,t_customer_authority ta where c.id=ta.customer_id and a.id=ta.authority_id and c.username=?");

         */

        //使用UserDetailService进行认证
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);


    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/login/**").permitAll()
                .antMatchers("/details/common/**").hasRole("common")
                .antMatchers("/detail/vip/**").hasRole("vip")
                .anyRequest().authenticated()
                .and().formLogin();
        //自定义用户登陆控制
        http.formLogin().loginPage("/userLogin").permitAll()
                .usernameParameter("name")
                .passwordParameter("pwd")
                .defaultSuccessUrl("/")
                .failureForwardUrl("/userLogin/error");


        //自定义用户退出
        http.logout().logoutUrl("/mylogout").logoutSuccessUrl("/");
    }
}
